using MyTimer;
using Services;
using Services.Event;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;

namespace Gobang
{
    public class PredictionManager : MonoBehaviour
    {
        public static PredictionManager FindInstance() => GameObject.Find("Prediction").GetComponent<PredictionManager>();

        private IEventSystem eventSystem;
        private ChessboardMono chessboard;
        private GameManager gameManager;
        private IPredictionLaucher laucher;

        private Metronome metronome;
        [SerializeField]
        [Range(0.1f, 5f)]
        private float refreshInterval;

        public UnityAction AfterPredictionChange;

        public List<PredictionPointData> predictions;

        public int count;

        private void AfterChessChange()
        {
            switch (gameManager.gameMode)
            {
                case EGameMode.WinRate:
                    if (chessboard.winner == 0)
                        laucher.Restart();
                    break;
                case EGameMode.PVE:
                    if (chessboard.nextChess == (gameManager.computerFirst ? 1 : 2) && chessboard.winner == 0)
                        laucher.Restart();
                    else
                        laucher.Stop();
                    break;
            }
        }

        private void AfterGameStateChange(bool isPlaying)
        {
            predictions.Clear();
            if (!isPlaying)
                laucher.Stop();
        }

        private void UpdatePrediction(float _)
        {
            if (laucher.IsRunning)
            {
                laucher.GetPrediction(predictions, count);
                AfterPredictionChange?.Invoke();
            }
        }

        private void Awake()
        {
            gameManager = ServiceLocator.Get<GameManager>();
            chessboard = ChessboardMono.FindInstance();
            laucher = GetComponentInChildren<IPredictionLaucher>();
            eventSystem = ServiceLocator.Get<IEventSystem>();
            predictions = new List<PredictionPointData>();
            metronome = new Metronome();
            metronome.AfterCompelete += UpdatePrediction;
        }

        private void OnEnable()
        {
            eventSystem.AddListener<bool>(EEvent.AfterGameStateChange, AfterGameStateChange);
            metronome.Initialize(refreshInterval);
            chessboard.AfterChessChange += AfterChessChange;
        }

        private void OnDisable()
        {
            eventSystem.AddListener<bool>(EEvent.AfterGameStateChange, AfterGameStateChange);
            metronome.Paused = true;
            chessboard.AfterChessChange -= AfterChessChange;
        }
    }
}